package cn.hchaojie.camp.day08;

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.property.DoubleProperty;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollBar;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import javafx.util.Duration;

public class BallGame extends Application {

	@Override
	public void start(Stage primaryStage) throws Exception {
		BallPane pane = new BallPane();
		
		Button add = new Button("+");
		Button remove = new Button("-");
		add.setOnAction(e -> pane.add());
		remove.setOnAction(e -> pane.substract());
		
		HBox hbox = new HBox(10);
		hbox.setAlignment(Pos.CENTER);
		hbox.getChildren().addAll(add, remove);
		
		pane.setOnMousePressed(e -> pane.pause());
		pane.setOnMouseReleased(e -> pane.play());
		
		ScrollBar speedBar = new ScrollBar();
		speedBar.setMax(20);
		speedBar.setValue(10);
		
		pane.rateProperty().bind(speedBar.valueProperty());
		
		BorderPane root = new BorderPane();
		root.setTop(speedBar);
		root.setBottom(hbox);
		root.setCenter(pane);
				
		Scene scene = new Scene(root, 250, 150);
		primaryStage.setScene(scene);

		primaryStage.show();
	}

	public static void main(String[] args) {
		launch(args);
	}
	
	private class BallPane extends Pane {
		private Timeline animation;
		
		public BallPane() {
			animation = new Timeline(
				new KeyFrame(Duration.millis(50), e -> moveBall()));
			animation.setCycleCount(Timeline.INDEFINITE);
			animation.play();
		}
		
		public void add() {
			Color c = new Color(Math.random(), Math.random(), Math.random(), 0.5);
			getChildren().add(new Ball(30, 30, 20, c));
		}
		
		public void substract() {
			if (getChildren().size() > 0) {
				getChildren().remove(getChildren().size() - 1);
			}
		}
		
		public void speedUp() {
			animation.setRate(animation.getRate() + 0.1);
		}
		
		public void slowDown() {
			animation.setRate(Math.max(0, animation.getRate() - 0.1));
		}
		
		public DoubleProperty rateProperty() {
			return animation.rateProperty();
		}
		
		protected void moveBall() {
			for (Node node : this.getChildren()) {
				Ball ball = (Ball) node;
				// 检查边界
				if (ball.getCenterX() < ball.getRadius()
						|| ball.getCenterX() > getWidth() - ball.getRadius()) {
					ball.dx *= -1;	// 改变运动方向
				}
				
				if (ball.getCenterY() < ball.getRadius()
						|| ball.getCenterY() > getHeight() - ball.getRadius()) {
					ball.dy *= -1;
				}
				
				ball.setCenterX(ball.dx + ball.getCenterX());
				ball.setCenterY(ball.dy + ball.getCenterY());
			}
		}
		
		public void play() {
			animation.play();
		}
		
		public void pause() {
			animation.pause();
		}
	}
	
	private class Ball extends Circle {
		private double dx = 1, dy = 1;
		
		public Ball(double x, double y, double radius, Color c) {
			super(x, y, radius);
			setFill(c);
		}
	}
}